<template>
  <el-form
    ref="formRef"
    :model="formData"
    :rules="formRules"
    :label-width="config.labelWidth || '80px'"
    :inline="config.inline || false"
    v-bind="config.formProps || {}">
    <!-- 行内表单布局 -->
    <template v-if="config.inline">
      <el-form-item
        v-for="item in formItems"
        :key="item.prop"
        :label="item.label"
        :prop="item.prop"
        :rules="item.rules"
        v-bind="item.formItemProps || {}">
        <!-- 表单控件内容 -->
        <!-- 输入框 -->
        <el-input
          v-if="item.type === 'input'"
          v-model="formData[item.prop]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :maxlength="item.maxlength"
          :show-password="item.showPassword"
          :type="item.inputType || 'text'"
          :style="item.style"
          v-bind="item.props || {}"
          @keyup.enter="config.keyup ? handleButtonClick({ action: 'submit' }) : null" />

        <!-- 数字输入框 -->
        <el-input-number
          v-else-if="item.type === 'number'"
          v-model="formData[item.prop]"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :min="item.min"
          :max="item.max"
          :step="item.step || 1"
          v-bind="item.props || {}" />

        <!-- 选择器 -->
        <el-select
          v-else-if="item.type === 'select'"
          v-model="formData[item.prop]"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :multiple="item.multiple"
          :clearable="item.clearable !== false"
          :style="item.style"
          v-bind="item.props || {}">
          <el-option
            v-for="option in getOptions(item)"
            :key="getOptionValue(option, item)"
            :label="getOptionLabel(option, item)"
            :value="getOptionValue(option, item)"
            :disabled="getOptionDisabled(option, item)" />
        </el-select>

        <!-- 单选框组 -->
        <el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.prop]" v-bind="item.props || {}">
          <el-radio
            v-for="option in getOptions(item)"
            :key="getOptionValue(option, item)"
            :value="getOptionValue(option, item)"
            :disabled="getOptionDisabled(option, item)">
            {{ getOptionLabel(option, item) }}
          </el-radio>
        </el-radio-group>

        <!-- 复选框组 -->
        <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.prop]" v-bind="item.props || {}">
          <el-checkbox
            v-for="option in getOptions(item)"
            :key="getOptionValue(option, item)"
            :value="getOptionValue(option, item)"
            :disabled="getOptionDisabled(option, item)">
            {{ getOptionLabel(option, item) }}
          </el-checkbox>
        </el-checkbox-group>

        <!-- 日期选择器 -->
        <el-date-picker
          v-else-if="item.type === 'date'"
          v-model="formData[item.prop]"
          :type="item.dateType || 'date'"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :value-format="item.valueFormat || 'YYYY-MM-DD'"
          :start-placeholder="item.startPlaceholder"
          :end-placeholder="item.endPlaceholder"
          :range-separator="item.rangeSeparator || '-'"
          :style="item.style"
          v-bind="item.props || {}" />

        <!-- 时间选择器 -->
        <el-time-picker
          v-else-if="item.type === 'time'"
          v-model="formData[item.prop]"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :value-format="item.valueFormat || 'HH:mm:ss'"
          v-bind="item.props || {}" />

        <!-- 开关 -->
        <el-switch
          v-else-if="item.type === 'switch'"
          v-model="formData[item.prop]"
          :active-value="item.activeValue || true"
          :inactive-value="item.inactiveValue || false"
          :active-text="item.activeText"
          :inactive-text="item.inactiveText"
          v-bind="item.props || {}" />

        <!-- 文本域 -->
        <el-input
          v-else-if="item.type === 'textarea'"
          v-model="formData[item.prop]"
          type="textarea"
          :placeholder="item.placeholder || `请输入${item.label}`"
          :rows="item.rows || 4"
          :maxlength="item.maxlength"
          v-bind="item.props || {}" />

        <!-- 树形选择器 -->
        <el-tree-select
          v-else-if="item.type === 'tree-select'"
          v-model="formData[item.prop]"
          :data="item.options || []"
          :props="item.treeProps || { value: 'id', label: 'label', children: 'children' }"
          :placeholder="item.placeholder || `请选择${item.label}`"
          :check-strictly="item.checkStrictly"
          :multiple="item.multiple"
          v-bind="item.props || {}" />

        <!-- 自定义插槽 -->
        <slot v-else-if="item.type === 'slot'" :name="item.slotName || item.prop" :form-data="formData" :item="item" />
      </el-form-item>
    </template>

    <!-- 栅格表单布局 -->
    <template v-else>
      <el-row :gutter="config.gutter || 20">
        <template v-for="item in formItems" :key="item.prop">
          <!-- 一级标题 -->
          <el-col v-if="item.props?.formTitle" :span="24" class="form-title-wrapper">
            <span class="form-title-text">{{ item.props.formTitle }}</span>
          </el-col>
          <!-- 二级标题 -->
          <el-col v-if="item.props?.formTitleTwo" :span="24" class="form-title-wrapper">
            <span class="form-title-text-two" :style="{ marginLeft: item.props.left || '0px' }">
              {{ item.props.formTitleTwo }}
            </span>
          </el-col>
          <el-col
            :span="item.span || config.defaultSpan || 8"
            :offset="item.offset || 0"
            :pull="item.pull || 0"
            class="form-col">
            <el-form-item
              :label="item.label"
              :prop="item.prop"
              :rules="item.rules"
              v-bind="item.formItemProps || {}"
              :class="{ 'long-label': item.props?.longLabel }">
              <!-- 输入框 -->
              <el-input
                v-if="item.type === 'input'"
                v-model="formData[item.prop]"
                :placeholder="item.placeholder || `请输入${item.label}`"
                :maxlength="item.maxlength"
                :show-password="item.showPassword"
                :type="item.inputType || 'text'"
                :style="item.style"
                v-bind="item.props || {}"
                @keyup.enter="config.keyup ? handleButtonClick({ action: 'submit' }) : null" />

              <!-- 数字输入框 -->
              <el-input-number
                v-else-if="item.type === 'number'"
                v-model="formData[item.prop]"
                :placeholder="item.placeholder || `请输入${item.label}`"
                :min="item.min"
                :max="item.max"
                :step="item.step || 1"
                v-bind="item.props || {}" />

              <!-- 选择器 -->
              <el-select
                v-else-if="item.type === 'select'"
                v-model="formData[item.prop]"
                :placeholder="item.placeholder || `请选择${item.label}`"
                :multiple="item.multiple"
                :clearable="item.clearable !== false"
                :style="item.style"
                v-bind="item.props || {}">
                <el-option
                  v-for="option in getOptions(item)"
                  :key="getOptionValue(option, item)"
                  :label="getOptionLabel(option, item)"
                  :value="getOptionValue(option, item)"
                  :disabled="getOptionDisabled(option, item)" />
              </el-select>

              <!-- 单选框组 -->
              <el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.prop]" v-bind="item.props || {}">
                <el-radio
                  v-for="option in getOptions(item)"
                  :key="getOptionValue(option, item)"
                  :value="getOptionValue(option, item)"
                  :disabled="getOptionDisabled(option, item)">
                  {{ getOptionLabel(option, item) }}
                </el-radio>
              </el-radio-group>

              <!-- 复选框组 -->
              <el-checkbox-group
                v-else-if="item.type === 'checkbox'"
                v-model="formData[item.prop]"
                v-bind="item.props || {}">
                <el-checkbox
                  v-for="option in getOptions(item)"
                  :key="getOptionValue(option, item)"
                  :value="getOptionValue(option, item)"
                  :disabled="getOptionDisabled(option, item)">
                  {{ getOptionLabel(option, item) }}
                </el-checkbox>
              </el-checkbox-group>

              <!-- 日期选择器 -->
              <el-date-picker
                v-else-if="item.type === 'date'"
                v-model="formData[item.prop]"
                :type="item.dateType || 'date'"
                :placeholder="item.placeholder || `请选择${item.label}`"
                :value-format="item.valueFormat || 'YYYY-MM-DD'"
                :start-placeholder="item.startPlaceholder"
                :end-placeholder="item.endPlaceholder"
                :range-separator="item.rangeSeparator || '-'"
                :style="item.style"
                v-bind="item.props || {}" />

              <!-- 时间选择器 -->
              <el-time-picker
                v-else-if="item.type === 'time'"
                v-model="formData[item.prop]"
                :placeholder="item.placeholder || `请选择${item.label}`"
                :value-format="item.valueFormat || 'HH:mm:ss'"
                v-bind="item.props || {}" />

              <!-- 开关 -->
              <el-switch
                v-else-if="item.type === 'switch'"
                v-model="formData[item.prop]"
                :active-value="item.activeValue || true"
                :inactive-value="item.inactiveValue || false"
                :active-text="item.activeText"
                :inactive-text="item.inactiveText"
                v-bind="item.props || {}" />

              <!-- 文本域 -->
              <el-input
                v-else-if="item.type === 'textarea'"
                v-model="formData[item.prop]"
                type="textarea"
                :placeholder="item.placeholder || `请输入${item.label}`"
                :rows="item.rows || 4"
                :maxlength="item.maxlength"
                v-bind="item.props || {}" />

              <!-- 树形选择器 -->
              <el-tree-select
                v-else-if="item.type === 'tree-select'"
                v-model="formData[item.prop]"
                :data="item.options || []"
                :props="item.treeProps || { value: 'id', label: 'label', children: 'children' }"
                :placeholder="item.placeholder || `请选择${item.label}`"
                :check-strictly="item.checkStrictly"
                :multiple="item.multiple"
                v-bind="item.props || {}" />

              <!-- 自定义插槽 -->
              <slot
                v-else-if="item.type === 'slot'"
                :name="item.slotName || item.prop"
                :form-data="formData"
                :item="item" />
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </template>

    <!-- 表单操作按钮 -->
    <el-form-item v-if="config.showButtons !== false">
      <el-button
        v-for="button in formButtons"
        :key="button.text"
        :type="button.type || 'default'"
        :loading="button.loading"
        :disabled="button.disabled"
        @click="handleButtonClick(button)"
        v-bind="button.props || {}">
        {{ button.text }}
      </el-button>
    </el-form-item>
    <el-form-item v-if="config.showAdvancedSearch">
      <el-button type="primary" link @click="handleSearchCut">
        高级搜索
        <el-icon v-show="searchCut === '0'"><ArrowDown /></el-icon>
        <el-icon v-show="searchCut === '1'"><ArrowUp /></el-icon>
      </el-button>
    </el-form-item>
  </el-form>
</template>

<script setup>
import { computed, ref, watch, nextTick } from 'vue'
import { ArrowDown, ArrowUp } from '@element-plus/icons-vue'

const props = defineProps({
  // 表单配置
  config: {
    type: Object,
    default: () => ({}),
  },
  // 表单项配置
  items: {
    type: Array,
    default: () => [],
  },
  // 表单数据
  modelValue: {
    type: Object,
    default: () => ({}),
  },
  // 字典数据
  dictData: {
    type: Object,
    default: () => ({}),
  },
  // 选项数据
  optionData: {
    type: Object,
    default: () => ({}),
  },
})

const emit = defineEmits(['update:modelValue', 'submit', 'reset', 'button-click'])

const formRef = ref()
const formData = ref({})
let isInternalUpdate = false
const searchCut = ref('0')
const showAdvanced = ref(false) // 控制是否显示高级搜索项

// 监听外部数据变化
watch(
  () => props.modelValue,
  newVal => {
    if (!isInternalUpdate) {
      formData.value = { ...newVal }
    }
  },
  { immediate: true, deep: true }
)

// 监听内部数据变化
watch(
  formData,
  newVal => {
    isInternalUpdate = true
    emit('update:modelValue', { ...newVal })
    nextTick(() => {
      isInternalUpdate = false
    })
  },
  { deep: true }
)

// 计算表单项
const formItems = computed(() => {
  // 根据 showAdvanced 的值过滤表单项
  return props.items.filter((item, index) => {
    if (props.config.showAdvancedSearch === true) {
      // 开启高级搜索
      if (showAdvanced.value) {
        return item.hidden !== false
      } else if (showAdvanced.value === false) {
        let indexx = null
        props.items.forEach((item, idx) => {
          if (!item.hidden && indexx === null) {
            indexx = idx
          } else {
            formData.value[item.prop] = null
          }
        })
        return index === indexx
      }
    } else {
      return !item.hidden
    }
  })
})

// 计算表单规则
const formRules = computed(() => {
  const rules = {}
  props.items.forEach(item => {
    if (item.rules) {
      rules[item.prop] = item.rules
    }
  })
  return rules
})

// 计算表单按钮
const formButtons = computed(() => {
  return (
    props.config.buttons || [
      { text: '提交', type: 'primary', action: 'submit' },
      { text: '重置', action: 'reset' },
    ]
  )
})

// 获取选项数据
const getOptions = item => {
  if (item.options) {
    return item.options
  }
  if (item.dictKey && props.dictData[item.dictKey]) {
    return props.dictData[item.dictKey]
  }
  if (item.optionKey && props.optionData[item.optionKey]) {
    return props.optionData[item.optionKey]
  }
  return []
}

// 获取选项值
const getOptionValue = (option, item) => {
  const valueKey = item.optionProps?.value || 'value'
  return option[valueKey]
}

// 获取选项标签
const getOptionLabel = (option, item) => {
  const labelKey = item.optionProps?.label || 'label'
  return option[labelKey]
}

// 获取选项禁用状态
const getOptionDisabled = (option, item) => {
  const disabledKey = item.optionProps?.disabled || 'disabled'
  const disabledValue = item.optionProps?.disabledValue

  // 如果没有设置禁用值，则使用默认的布尔值判断
  if (disabledValue === undefined) {
    return option[disabledKey] || false
  }

  // 如果设置了禁用值，则比较选项的值是否等于禁用值
  return option[disabledKey] === disabledValue
}
// 高级搜索切换
const handleSearchCut = () => {
  searchCut.value = searchCut.value === '0' ? '1' : '0'
  showAdvanced.value = !showAdvanced.value

  console.log('searchCut:', searchCut.value, 'showAdvanced:', showAdvanced.value)
}
// 按钮点击处理
const handleButtonClick = button => {
  if (button.action === 'submit') {
    handleSubmit()
  } else if (button.action === 'reset') {
    handleReset()
  } else {
    emit('button-click', button, formData.value)
  }
}

// 表单提交
const handleSubmit = () => {
  formRef.value.validate(valid => {
    if (valid) {
      emit('submit', formData.value)
    }
  })
}

// 表单重置
const handleReset = () => {
  formRef.value.resetFields()
  nextTick(() => {
    emit('reset')
  })
}

// 表单验证
const validate = () => {
  return formRef.value.validate()
}

// 重置表单验证
const resetValidation = () => {
  formRef.value.resetFields()
}

// 清空表单验证
const clearValidation = () => {
  formRef.value.clearValidate()
}

// 暴露方法给父组件
defineExpose({
  validate,
  resetValidation,
  clearValidation,
  formRef,
})
</script>

<style lang="scss" scoped>
.form-col {
  .el-form-item {
    width: 100%;
  }
}

:deep(.el-form-item__content) {
  display: inline-block;
}
</style>
